﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Web;
using System.Configuration;

namespace PickGold.Web
{
	/// <summary>
	/// 请求解析类。
	/// </summary>
	public class NameValueReqeust : NameValueCollection
	{
		private HttpContext _Context;
		private NameValueReqeustOption[] _Options;

		/// <summary>
		/// 构造一个解析实例。
		/// </summary>
		/// <param name="context">当前请求上下文。</param>
		public NameValueReqeust(HttpContext context) : this(context, null) { }

		/// <summary>
		/// 构造一个解析实例。
		/// </summary>
		/// <param name="context">当前请求上下文。</param>
		/// <param name="options">解析选项；默认，先尝试取 Query 数据，如果未取则尝试取 Form 数据。</param>
		public NameValueReqeust(HttpContext context, params NameValueReqeustOption[] options) : base(0)//context.Request.Params
		{
			this._Context = context;
			this._Options = options;
			if (this._Options != null && this._Options.Length > 0)
				return;

			if (this._Context.Request.Form.Count > 0)
				this._Options = new NameValueReqeustOption[] { NameValueReqeustOption.Form, NameValueReqeustOption.Query };
			else
				this._Options = new NameValueReqeustOption[] { NameValueReqeustOption.Query };
		}

		/// <summary>
		/// Gets the values at the specified index of the System.Collections.Specialized.NameValueCollection combined into one comma-separated list.
		/// </summary>
		/// <param name="index">The zero-based index of the entry that contains the values to get from the collection.</param>
		/// <returns>A System.String that contains a comma-separated list of the values at the specified index of the System.Collections.Specialized.NameValueCollection, if found; otherwise, null.</returns>
		public override string Get(int index)
		{
			return this._Context.Request.Params[index];
		}

		/// <summary>
		/// Gets the values associated with the specified key from the System.Collections.Specialized.NameValueCollection combined into one comma-separated list.
		/// </summary>
		/// <param name="name">The System.String key of the entry that contains the values to get. The key can be null.</param>
		/// <returns>A System.String that contains a comma-separated list of the values associated with the specified key from the System.Collections.Specialized.NameValueCollection, if found; otherwise, null.</returns>
		public override string Get(string name)
		{
			var v = name;
			for (var i = 0; i < this._Options.Length; i++)
			{
				switch (this._Options[i])
				{
					case NameValueReqeustOption.Query:
						v = this._Context.Request.QueryString[name];
						if (v != null)//if (!string.IsNullOrEmpty(value))
							return v;

						break;
					case NameValueReqeustOption.Form:
						v = this._Context.Request.Form[name];
						if (v != null)//if (!string.IsNullOrEmpty(value))
							return v;

						break;
					case NameValueReqeustOption.Cookie:
						if (this._Context.Request.Cookies[name] != null)
						{
							v = this._Context.Request.Cookies[name].Value;
							if (v != null)//if (!string.IsNullOrEmpty(value))
								return v;
						}
						break;
					case NameValueReqeustOption.Header:
						v = this._Context.Request.Headers[name];
						if (v != null)//if (!string.IsNullOrEmpty(value))
							return v;

						break;
					case NameValueReqeustOption.All:
						v = this._Context.Request.Params[name];
						if (v != null)//if (!string.IsNullOrEmpty(value))
							return v;

						break;
				}
			}
			return null;
		}

		/// <summary>
		/// Gets the values at the specified index of the System.Collections.Specialized.NameValueCollection.
		/// </summary>
		/// <param name="index">The zero-based index of the entry that contains the values to get from the collection.</param>
		/// <returns>A System.String array that contains the values at the specified index of the System.Collections.Specialized.NameValueCollection, if found; otherwise, null.</returns>
		public override string[] GetValues(int index)
		{
			return this._Context.Request.Params.GetValues(index);
		}

		/// <summary>
		/// Gets the values at the specified index of the System.Collections.Specialized.NameValueCollection.
		/// </summary>
		/// <param name="name">The zero-based index of the entry that contains the values to get from the collection.</param>
		/// <returns>A System.String array that contains the values at the specified index of the System.Collections.Specialized.NameValueCollection, if found; otherwise, null.</returns>
		public override string[] GetValues(string name)
		{
			var vs = new string[] { };
			for (var i = 0; i < this._Options.Length; i++)
			{
				switch (this._Options[i])
				{
					case NameValueReqeustOption.Query:
						vs = this._Context.Request.QueryString.GetValues(name);
						if (vs != null)//if (!string.IsNullOrEmpty(value))
							return vs;

						break;
					case NameValueReqeustOption.Form:
						vs = this._Context.Request.Form.GetValues(name);
						if (vs != null)//if (!string.IsNullOrEmpty(value))
							return vs;

						break;
					case NameValueReqeustOption.Cookie:
						var cookie = this._Context.Request.Cookies[name];
						if (cookie != null)
						{
							if (cookie.HasKeys)
							{
								var cv = this._Context.Request.Cookies[name].Values;
								if (cv != null)
								{
									var ls = new List<string>();
									for (var ii = 0; ii < cv.Count; ii++)
									{
										vs = cv.GetValues(ii);
										if (vs != null && vs.Length > 0)
											ls.AddRange(vs);
									}
									vs = ls.ToArray();
								}
								else
								{
									vs = new string[] { cookie.Value };
								}
							}
							else
							{
								vs = new string[] { cookie.Value };
							}
							if (vs != null)//if (!string.IsNullOrEmpty(value))
								return vs;
						}
						break;
					case NameValueReqeustOption.Header:
						vs = this._Context.Request.Headers.GetValues(name);
						if (vs != null)//if (!string.IsNullOrEmpty(value))
							return vs;

						break;
					case NameValueReqeustOption.All:
						vs = this._Context.Request.Params.GetValues(name);
						if (vs != null)//if (!string.IsNullOrEmpty(value))
							return vs;

						break;
				}
			}
			return null;
		}

		/// <summary>
		/// 尝试获取数据。
		/// </summary>
		/// <param name="name"></param>
		/// <param name="value"></param>
		/// <returns></returns>
		private bool __TryGetValue__(string name, out string value)
		{
			for (var i = 0; i < this._Options.Length; i++)
			{
				switch (this._Options[i])
				{
					case NameValueReqeustOption.Query:
						value = this._Context.Request.QueryString[name];
						if (value != null)//if (!string.IsNullOrEmpty(value))
							return true;

						break;
					case NameValueReqeustOption.Form:
						value = this._Context.Request.Form[name];
						if (value != null)//if (!string.IsNullOrEmpty(value))
							return true;

						break;
					case NameValueReqeustOption.Cookie:
						if (this._Context.Request.Cookies[name] != null)
						{
							value = this._Context.Request.Cookies[name].Value;
							if (value != null)//if (!string.IsNullOrEmpty(value))
								return true;
						}
						break;
					case NameValueReqeustOption.Header:
						value = this._Context.Request.Headers[name];
						if (value != null)//if (!string.IsNullOrEmpty(value))
							return true;

						break;
					case NameValueReqeustOption.All:
						value = this._Context.Request.Params[name];
						if (value != null)//if (!string.IsNullOrEmpty(value))
							return true;

						break;
				}
			}
			value = null;
			return false;
		}
	}

	/// <summary>
	/// 取值的选项方式。
	/// </summary>
	public enum NameValueReqeustOption : byte
	{
		/// <summary>
		/// 取 Get 的 Query 值。
		/// </summary>
		Query = 0,
		/// <summary>
		/// 取 Post 的 Form 值。
		/// </summary>
		Form = 1,
		/// <summary>
		/// 取 Cookie 值。
		/// </summary>
		Cookie = 2,
		/// <summary>
		/// 取 Header 值。
		/// </summary>
		Header = 3,
		/// <summary>
		/// 取请求所有值。
		/// </summary>
		All = 4
	}
}
